﻿/////////////////////////////////////////////////////////////////////////////////////////////
// <copyright file="SessionRunspace.cs" company="Microsoft Corporation">
//     Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
/////////////////////////////////////////////////////////////////////////////////////////////

namespace Microsoft.LiveAtEdu.Samples.Powershell
{
    using System;
    using System.Collections.ObjectModel;
    using System.Management.Automation;
    using System.Management.Automation.Runspaces;

    /// <summary>
    /// Abstracts various session and runspace. This also contain some utility 
    /// functions that could be used by all derived classes.
    /// </summary>
    public abstract class SessionRunspace
    {
        /// <summary>
        /// Gets or sets Runspace property.
        /// </summary>
        public Runspace Runspace
        {
            get;
            protected set;
        }

        /// <summary>
        /// Gets or sets Session.
        /// </summary>
        public PSSession PSSession
        {
            get;
            protected set;
        }

        /// <summary>
        /// Gets or sets session type.
        /// </summary>
        public SessionType SessionType
        {
            get;
            protected set;
        }

        /// <summary>
        /// Implement this method so that framework can give callback to close the session instance.
        /// </summary>
        public abstract void CloseInstance();

        /// <summary>
        /// Execute a powershell command.
        /// </summary>
        /// <param name="command">Powershell command.</param>
        /// <returns>Collection of PSObjects</returns>
        public Collection<PSObject> ExecuteCommand(PSCommand command)
        {
            return this.ExecuteCommand<PSObject>(command);
        }

        /// <summary>
        /// Execute a powershell command.
        /// </summary>
        /// <typeparam name="T">Type of command execution result.</typeparam>
        /// <param name="command">Powershell command.</param>
        /// <returns>Result collection.</returns>
        public Collection<T> ExecuteCommand<T>(PSCommand command)
        {
            if (command == null)
            {
                throw new ArgumentOutOfRangeException("command");
            }

            using (PowerShell ps = PowerShell.Create())
            {
                ps.Commands = command;
                ps.Runspace = this.Runspace;

                return ps.Invoke<T>();
            }
        }
    }
}
